package com.taldh.netty.io.reactor;

import com.taldh.netty.common.util.Dateutil;
import com.taldh.netty.common.util.Logger;
import com.taldh.netty.common.util.Print;
import com.taldh.netty.io.NioDemoConfig;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;

public class EchoClient {

    public void start() throws IOException {
        InetSocketAddress address = new InetSocketAddress(
                NioDemoConfig.SOCKET_SERVER_IP,
                NioDemoConfig.SOCKET_SERVER_PORT
        );

        // 1. 获取通道 channel
        SocketChannel socketChannel =SocketChannel.open(address);
        // 2. 切换成非阻塞模式
        socketChannel.configureBlocking(false);
        // 不断自旋，等待连接完成，或者做一些其它事情
        while (!socketChannel.finishConnect()) {

        }
        Print.tcfo("客户端启动成功！");

        // 启动接受线程
        Processer processer = new Processer(socketChannel);
        new Thread(processer).start();
    }

    class Processer implements  Runnable {

        final Selector selector;
        final SocketChannel channel;

        public Processer(SocketChannel channel) throws IOException {
            this.selector = Selector.open();
            this.channel = channel;
            channel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
        }

        @Override
        public void run() {
            try {
                while (!Thread.interrupted()) {
                    selector.select();
                    Set<SelectionKey> selectionKeys = selector.selectedKeys();
                    Iterator<SelectionKey> it = selectionKeys.iterator();
                    while (it.hasNext()) {
                        SelectionKey sk = it.next();
                        if (sk.isWritable()) {
                            ByteBuffer byteBuffer = ByteBuffer.allocate(NioDemoConfig.SEND_BUFFER_SIZE);
                            Scanner scanner = new Scanner(System.in);
                            Print.tcfo("请输入发送的内容：");
                            if (scanner.hasNext()) {
                                SocketChannel socketChannel = (SocketChannel) sk.channel();
                                String next = scanner.next();
                                byteBuffer.put((Dateutil.getNow() + " >> " + next).getBytes());
                                byteBuffer.flip();
                                socketChannel.write(byteBuffer);
                                byteBuffer.clear();
                            }
                        }
                        if (sk.isReadable()) {
                            // 若选择键的IO事件是“可读”事件,读取数据
                            SocketChannel socketChannel = (SocketChannel) sk.channel();

                            //读取数据
                            ByteBuffer byteBuffer = ByteBuffer.allocate(NioDemoConfig.SEND_BUFFER_SIZE);
                            int length = 0;
                            while ((length = socketChannel.read(byteBuffer)) > 0) {
                                byteBuffer.flip();
                                Logger.info("server echo : "+ new String(byteBuffer.array(), 0 , length));
                                byteBuffer.clear();
                            }

                        }
                        selectionKeys.clear();
                    }
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws IOException {
        new EchoClient().start();
    }

}
